package com.jeeplus.modules.sys.utils;

import com.google.gson.Gson;
import net.sf.json.JSONObject;
import okhttp3.*;
import org.apache.commons.io.IOUtils;
import org.apache.xmlbeans.impl.util.Base64;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

public class Des3Utils {
    private static final String ENCODE_SET = "UTF-8";

    //    "biz.datalk.cdydsk-201607"
    //            "20160719"
    // 密钥
    private final static String secretKey = "biz.datalk123.dkwxwt1234";
    // 向量
    private final static String iv = "datalk88";
    // 加解密统一使用的编码方式
    private final static String encoding = "utf-8";

    /**
     * 3DES加密
     *
     * @param plainText 普通文本
     * @return 返回加密后的字符串
     * @throws Exception
     */
    public static String encode(String plainText) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        Key deskey = keyfactory.generateSecret(spec);

        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
        return new String(Base64.encode(encryptData));
    }

    public static String decode(String content) throws Exception {
        Key deskey = null;
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
        keyfactory.generateSecret(spec);
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
        byte[] decryptData = cipher.doFinal(Base64.decode(content.getBytes()));
        return new String(decryptData, ENCODE_SET);
    }

    /**
     * 使用自定义密匙的DES3解密
     *
     * @param encryptText 密文
     * @return 原文
     * @throws Exception
     */
    public static String decryptWithKey(String encryptText)
            throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException,
            InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        Key deskey = null;
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
        keyfactory.generateSecret(spec);
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
        byte[] decryptData = cipher.doFinal(Base64.decode(encryptText.getBytes()));
        return new String(decryptData, ENCODE_SET);
    }

    /**
     * DES加密
     *
     * @param datasource
     * @return
     */
    public static String desEncode(String datasource) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec("datalk88".getBytes("utf-8"));
            //创建一个密匙工厂，然后用它把DESKeySpec转换成
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            //Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("DES");
            //用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
            //现在，获取数据并加密
            byte[] temp = Base64.encode(cipher.doFinal(datasource.getBytes("UTF-8")));
            return IOUtils.toString(temp, "UTF-8");
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * DES解密
     *
     * @return
     */
    public static String desDecode(String src) throws Exception {
        // DES算法要求有一个可信任的随机数源
        SecureRandom random = new SecureRandom();
        // 创建一个DESKeySpec对象
        DESKeySpec desKey = new DESKeySpec("datalk88".getBytes("utf-8"));
        // 创建一个密匙工厂
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        // 将DESKeySpec对象转换成SecretKey对象
        SecretKey securekey = keyFactory.generateSecret(desKey);
        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密匙初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, random);
        // 真正开始解密操作
        return IOUtils.toString(cipher.doFinal(Base64.decode(src.getBytes("UTF-8"))));
    }

    public static void main(String[] args) throws Exception {
        String encodeStr = desEncode("123456789878987678");
        System.out.println(URLEncoder.encode(encodeStr, "UTF-8"));
        System.out.println(encodeStr);
        String decodeStr = desDecode("w/TGMY5h5uEA4tSOJQMMVKS9mUjnzSvhVNMapIZHxowmHcCbIwX3TkPasZ0vZ/8I7ihn6JL0+piktPwVHGoT4pkFm4MVOCpN");
        System.out.println(decodeStr);
    }

    public static int toCheckUserRC(String param,String url){
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("text/plain");
        RequestBody body = RequestBody.create(mediaType, "");
        try{
            Request request = new Request.Builder()
                    .url(url+"?params="+URLEncoder.encode(desEncode(param), "UTF-8"))
                    .method("POST", body)
                    .build();
            Response response = client.newCall(request).execute();
            return JSONObject.fromObject(desDecode(response.body().string().toString())).getJSONObject("data").getInt("isPersonnel");
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }

    }
}
